package com.yindian.cos.easy.security.authentication.login.social.weixin;

import com.alibaba.fastjson.JSONObject;
import com.yindian.cos.easy.security.authentication.login.social.core.AbstractAccessTokenFactory;
import com.yindian.cos.easy.security.authentication.login.social.core.AccessToken;
import com.yindian.cos.easy.security.constant.ProviderName;
import com.yindian.cos.easy.security.exception.AccessTokenException;
import com.yindian.cos.easy.security.properties.EasySecurityProperties;
import com.yindian.cos.easy.security.properties.WeiXinProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信获取access_token默认实现
 *
 * @author zhangchuanhao
 * @create 2018/11/20
 */
public class WeiXinAccessTokenFactory extends AbstractAccessTokenFactory {

    private EasySecurityProperties easySecurityProperties;

    private RestTemplate restTemplate;

    public WeiXinAccessTokenFactory(EasySecurityProperties easySecurityProperties, RestTemplate restTemplate) {
        this.easySecurityProperties = easySecurityProperties;
        this.restTemplate = restTemplate;
    }

    @Override
    public AccessToken getAccessToken(String code) {
        try {
            WeiXinProperties weiXinProperties = easySecurityProperties.getWeixin();

            String url = weiXinProperties.getAccessTokenUrl();
            url += "?grant_type=" + weiXinProperties.getGrantType();
            url += "&appid=" + weiXinProperties.getAppId();
            url += "&secret=" + weiXinProperties.getAppSecret();
            url += "&code=" + code;

            String result = restTemplate.getForObject(url, String.class);
            String accessTokenStr;
            String openId;
            Map<String, Object> map = new HashMap<>();
            if (StringUtils.contains(result, "access_token")) {
                WeiXinAccessToken weiXinAccessToken = JSONObject.parseObject(result, WeiXinAccessToken.class);
                accessTokenStr = weiXinAccessToken.getAccess_token();
                openId = weiXinAccessToken.getOpenid();
                map.put("weiXinAccessToken", weiXinAccessToken);
            } else {
                throw new AccessTokenException(ProviderName.WEIXIN + "登录获取access_token失败", result);
            }
            AccessToken accessToken = new AccessToken(accessTokenStr, openId, map);
            return accessToken;
        } catch (AccessTokenException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new AccessTokenException(ProviderName.WEIXIN + "登录获取access_token失败", ex.getCause());
        }
    }
}
